package com.tbit.uqbike.webmanager.handler;

import com.tbit.uqbike.annos.PreAuthorize;
import com.tbit.uqbike.constant.HttpStatus;
import com.tbit.uqbike.manager.exception.AuthenticationException;
import com.tbit.uqbike.object.value.LoginInfo;
import com.tbit.uqbike.service.base.TokenService;
import com.tbit.uqbike.service.business.impl.PermissionServiceImpl;
import com.tbit.uqbike.webmanager.util.ServletUtils;
import com.tbit.uqbike.webmanager.util.StringUtils;
import com.tbit.uqbike.webmanager.util.spring.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @author jing
 * @date 2021/3/2514:18
 * @Description:
 */
@Aspect
@Component
@Slf4j
public class PreAuthorizeAspect {

    @Autowired
    private PermissionServiceImpl ss;

    /**
     * 对标注有operateLog注解的进行拦截,@annotation表示标注了某个注解的所有方法。
     */
    @Pointcut("@annotation(com.tbit.uqbike.annos.PreAuthorize)")
    public void preAuthorizeAspect() {

    }

    @Before("preAuthorizeAspect()")
    public void doBefore(JoinPoint point) {
        handlPreAuthorize(point);
    }

    protected void handlPreAuthorize(final JoinPoint joinPoint) {
        // 获得注解
        PreAuthorize preAuthorize = getAnnotationLog(joinPoint);
        if (preAuthorize == null) {
            return;
        }
        // 获取当前的用户
        LoginInfo loginUser = SpringUtils.getBean(TokenService.class).getLoginInfo();
        if (StringUtils.isNotNull(loginUser)) {
            // 如果是超级管理员，则不过滤数据
            if (StringUtils.isNotNull(loginUser) && !loginUser.roleIsAdmin()) {
                hasPreAuthorize(preAuthorize);
            }
        }
    }

    protected void hasPreAuthorize(PreAuthorize preAuthorize) {
        if (!ss.hasPermi(preAuthorize.value())) {
            int code = HttpStatus.UNAUTHORIZED;
            String msg = StringUtils.format("请求访问：{}，认证失败，无法访问系统资源", ServletUtils.getRequest().getRequestURI());
            throw new AuthenticationException("401", code, msg);
        }
    }

    /**
     * 是否存在注解，如果存在就获取
     */
    private PreAuthorize getAnnotationLog(JoinPoint joinPoint) {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();

        if (method != null) {
            return method.getAnnotation(PreAuthorize.class);
        }
        return null;
    }


}
